home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / ole2book.zip / CHAP04.ZIP / CHAP04 / SCHMOO / SCHMOO.CPP < prev    next >
C/C++ Source or Header  |  1993-03-14  |  13KB  |  596 lines

  1. /*
  2.  * SCHMOO.CPP
  3.  *
  4.  * WinMain and CSchmooFrame implementations.
  5.  *
  6.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  7.  *
  8.  * Kraig Brockschmidt, Software Design Engineer
  9.  * Microsoft Systems Developer Relations
  10.  *
  11.  * Internet  :  kraigb@microsoft.com
  12.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  13.  */
  14.  
  15.  
  16.  
  17. //Must do this once or we can't define our own GUIDs (see compobj.h)
  18. #define INITCLSID
  19.  
  20. #include "schmoo.h"
  21.  
  22.  
  23. /*
  24.  * WinMain
  25.  *
  26.  * Purpose:
  27.  *  Main entry point of application.   Should register the app class
  28.  *  if a previous instance has not done so and do any other one-time
  29.  *  initializations.
  30.  */
  31.  
  32. int PASCAL WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR pszCmdLine, int nCmdShow)
  33.     {
  34.     LPCSchmooFrame  pFR;
  35.     FRAMEINIT       fi;
  36.     WPARAM          wRet;
  37.  
  38.     //Attempt to allocate and initialize the application
  39.     pFR=new CSchmooFrame(hInst, hPrev, pszCmdLine, nCmdShow);
  40.  
  41.     fi.idsMin=IDS_FRAMEMIN;
  42.     fi.idsMax=IDS_FRAMEMAX;
  43.     fi.idsStatMin=IDS_STATMESSAGEMIN;
  44.     fi.idsStatMax=IDS_STATMESSAGEMAX;
  45.     fi.idStatMenuMin=ID_MENUFILE;
  46.     fi.idStatMenuMax=ID_MENUHELP;
  47.     fi.iPosWindowMenu=WINDOW_MENU;
  48.     fi.cMenus=CMENUS;
  49.  
  50.     //If we can initialize pFR, start chugging messages
  51.     if (pFR->FInit(&fi))
  52.         wRet=pFR->MessageLoop();
  53.  
  54.     delete pFR;
  55.     return wRet;
  56.     }
  57.  
  58.  
  59.  
  60.  
  61. /*
  62.  * CSchmooFrame::CSchmooFrame
  63.  * CSchmooFrame::~CSchmooFrame
  64.  *
  65.  * Constructor Parameters:
  66.  *  hInst           HINSTANCE from WinMain
  67.  *  hInstPrev       HINSTANCE from WinMain
  68.  *  pszCmdLine      LPSTR from WinMain
  69.  *  nCmdShow        int from WInMain
  70.  */
  71.  
  72. CSchmooFrame::CSchmooFrame(HINSTANCE hInst, HINSTANCE hInstPrev
  73.     , LPSTR pszCmdLine, int nCmdShow)
  74.     : CFrame(hInst, hInstPrev, pszCmdLine, nCmdShow)
  75.     {
  76.     m_fInitialized=FALSE;
  77.     return;
  78.     }
  79.  
  80.  
  81. CSchmooFrame::~CSchmooFrame(void)
  82.     {
  83.     UINT        i;
  84.  
  85.     for (i=0; i<5; i++)
  86.         DeleteObject(m_hBmpLines[i]);
  87.  
  88.     if (m_fInitialized)
  89.         CoUninitialize();
  90.  
  91.     return;
  92.     }
  93.  
  94.  
  95.  
  96.  
  97. /*
  98.  * CSchmooFrame::FInit
  99.  *
  100.  * Purpose:
  101.  *  Call CoInitialize then calling down into the base class
  102.  *  initialization.
  103.  *
  104.  * Parameters:
  105.  *  pFI             LPFRAMEINIT containing initialization parameters.
  106.  *
  107.  * Return Value:
  108.  *  BOOL            TRUE if initialization succeeded, FALSE otherwise.
  109.  */
  110.  
  111. BOOL CSchmooFrame::FInit(LPFRAMEINIT pFI)
  112.     {
  113.     DWORD       dwVer;
  114.  
  115.     //Make sure COMPOBJ.DLL is the right version
  116.     dwVer=CoBuildVersion();
  117.  
  118.     if (rmm!=HIWORD(dwVer))
  119.         return FALSE;
  120.  
  121.     if (NOERROR!=CoInitialize(NULL))
  122.         return FALSE;
  123.  
  124.     m_fInitialized=TRUE;
  125.  
  126.     return CFrame::FInit(pFI);
  127.     }
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134. /*
  135.  * CSchmooFrame::CreateCClient
  136.  *
  137.  * Purpose:
  138.  *  Constructs a new client specific to the application.
  139.  *
  140.  * Parameters:
  141.  *  None
  142.  *
  143.  * Return Value:
  144.  *  LPCClient       Pointer to the new client object.
  145.  */
  146.  
  147. LPCClient CSchmooFrame::CreateCClient(void)
  148.     {
  149.     return (LPCClient)(new CSchmooClient(m_hInst));
  150.     }
  151.  
  152.  
  153.  
  154.  
  155.  
  156.  
  157. /*
  158.  * CSchmooFrame::FPreShowInit
  159.  *
  160.  * Purpose:
  161.  *  Called from FInit before intially showing the window.  We do whatever
  162.  *  else we want here, modifying nCmdShow as necessary which affects
  163.  *  ShowWindow in FInit.
  164.  *
  165.  * Parameters:
  166.  *  None
  167.  *
  168.  * Return Value:
  169.  *  BOOL            TRUE if this initialization succeeded, FALSE otherwise.
  170.  */
  171.  
  172. BOOL CSchmooFrame::FPreShowInit(void)
  173.     {
  174.     CreateLineMenu();
  175.     CheckLineSelection(IDM_LINESOLID);
  176.     m_pGB->Check(IDM_LINESOLID, TRUE);
  177.     return TRUE;
  178.     }
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185. /*
  186.  * CSchmooFrame::CreateLineMenu
  187.  *
  188.  * Purpose:
  189.  *  Initializes the bitmaps used to create the Line menu and replaces
  190.  *  the text items defined in the application resources with these
  191.  *  bitmaps.  Note that the contents of m_hBmpLines must be cleaned
  192.  *  up when the application terminates.
  193.  *
  194.  * Parameters:
  195.  *  None
  196.  *
  197.  * Return Value:
  198.  *  None
  199.  */
  200.  
  201. void CSchmooFrame::CreateLineMenu(void)
  202.     {
  203.     HMENU       hMenu;
  204.     HDC         hDC, hMemDC;
  205.     HPEN        hPen;
  206.     HGDIOBJ     hObj;
  207.     TEXTMETRIC  tm;
  208.     UINT        i, cx, cy;
  209.  
  210.  
  211.     hMenu=GetSubMenu(GetMenu(m_hWnd), 3);   //Line menu.
  212.     hDC=GetDC(m_hWnd);
  213.  
  214.     //Create each line in a menu item 8 chars wide, one char high.
  215.     GetTextMetrics(hDC, &tm);
  216.     cx=tm.tmAveCharWidth*8;
  217.     cy=tm.tmHeight;
  218.  
  219.     //Create a memory DC in which to draw lines, and bitmaps for each line.
  220.     hMemDC=CreateCompatibleDC(hDC);
  221.     ReleaseDC(m_hWnd, hDC);
  222.  
  223.     for (i=0; i<5; i++)
  224.         {
  225.         m_hBmpLines[i]=CreateCompatibleBitmap(hMemDC, cx, cy);
  226.         SelectObject(hMemDC, m_hBmpLines[i]);
  227.  
  228.         PatBlt(hMemDC, 0, 0, cx, cy, WHITENESS);
  229.  
  230.         hPen=CreatePen(i, 1, 0L);           //i==line style like PS_SOLID
  231.         hObj=SelectObject(hMemDC, hPen);
  232.  
  233.         MoveTo(hMemDC, 0,  cy/2);
  234.         LineTo(hMemDC, cx, cy/2);
  235.  
  236.         ModifyMenu(hMenu, IDM_LINEMIN+i, MF_BYCOMMAND | MF_BITMAP
  237.             , IDM_LINEMIN+i, (LPCSTR)MAKELONG(m_hBmpLines[i], 0));
  238.  
  239.         SelectObject(hMemDC, hObj);
  240.         DeleteObject(hPen);
  241.         }
  242.  
  243.     CheckMenuItem(hMenu, IDM_LINESOLID, MF_CHECKED);
  244.     DeleteDC(hMemDC);
  245.  
  246.     return;
  247.     }
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257. /*
  258.  * CSchmooFrame::CreateGizmos
  259.  *
  260.  * Purpose:
  261.  *  Procedure to create all the necessary gizmobar buttons.
  262.  *
  263.  * Parameters:
  264.  *  None
  265.  *
  266.  * Return Value:
  267.  *  UINT            Number of gizmos added to the bar.
  268.  */
  269.  
  270. UINT CSchmooFrame::CreateGizmos(void)
  271.     {
  272.     UINT            iLast;
  273.     UINT            uState=GIZMO_NORMAL;
  274.     UINT            utCmd =GIZMOTYPE_BUTTONCOMMAND;
  275.     UINT            utEx  =GIZMOTYPE_BUTTONATTRIBUTEEX;
  276.  
  277.     //Insert the standard ones.
  278.     iLast=CFrame::CreateGizmos();
  279.  
  280.     //Insert File Import in the 5th position and account for it in iLast.
  281.     m_pGB->Add(utCmd, 4, IDM_FILEIMPORT, 24, 22, NULL, m_hBmp, 2, uState);
  282.     iLast++;
  283.  
  284.     //Separator
  285.     m_pGB->Add(GIZMOTYPE_SEPARATOR, iLast++, 0, 6, 22, NULL, NULL, 0, uState);
  286.  
  287.     //For the Background bitmap, preserve our use of black (part of the image)
  288.     m_pGB->Add(utCmd, iLast++, IDM_COLORBACKGROUND, 24, 22, NULL, m_hBmp, 3
  289.                , GIZMO_NORMAL | PRESERVE_BLACK);
  290.  
  291.     m_pGB->Add(utCmd, iLast++, IDM_COLORLINE, 24, 22, NULL, m_hBmp, 4, uState);
  292.  
  293.     //Separator
  294.     m_pGB->Add(GIZMOTYPE_SEPARATOR, iLast++, 0, 6, 22, NULL, NULL, 0, uState);
  295.  
  296.     //Line styles.
  297.     m_pGB->Add(utEx, iLast++, IDM_LINESOLID,      24, 22, NULL, m_hBmp, 5, uState);
  298.     m_pGB->Add(utEx, iLast++, IDM_LINEDASH,       24, 22, NULL, m_hBmp, 6, uState);
  299.     m_pGB->Add(utEx, iLast++, IDM_LINEDOT,        24, 22, NULL, m_hBmp, 7, uState);
  300.     m_pGB->Add(utEx, iLast++, IDM_LINEDASHDOT,    24, 22, NULL, m_hBmp, 8, uState);
  301.     m_pGB->Add(utEx, iLast++, IDM_LINEDASHDOTDOT, 24, 22, NULL, m_hBmp, 9, uState);
  302.  
  303.     return iLast;
  304.     }
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313. /*
  314.  * CSchmooFrame::OnCommand
  315.  *
  316.  * Purpose:
  317.  *  WM_COMMAND handler for the Schmoo frame window that just processes
  318.  *  the line menu and the color menu leaving the CFrame to do everything
  319.  *  else.
  320.  *
  321.  * Parameters:
  322.  *  hWnd            HWND of the frame window.
  323.  *  wParam          WPARAM of the message.
  324.  *  lParam          LPARAM of the message.
  325.  *
  326.  * Return Value:
  327.  *  LRESULT         Return value for the message.
  328.  */
  329.  
  330. LRESULT CSchmooFrame::OnCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
  331.     {
  332.     LPCSchmooDoc    pDoc;
  333.     char            szFile[CCHPATHMAX];
  334.     BOOL            fOK;
  335.     UINT            i, uTemp;
  336.     COLORREF        rgColors[16];
  337.     CHOOSECOLOR     cc;
  338.  
  339.     COMMANDPARAMS(wID, wCode, hWndMsg);
  340.  
  341.     /*
  342.      * Don't bother with anything during first initialization,
  343.      * skipping many GizmoBar notifications.
  344.      */
  345.     if (m_fInit)
  346.         return 0L;
  347.  
  348.     pDoc=(LPCSchmooDoc)m_pCL->ActiveDocument();
  349.  
  350.     /*
  351.      * Check for the line style commands which are IDM_LINEMIN+<style>.
  352.      * We handle this by changing the menu and toolbar, then we pass
  353.      * it to the document for real processing.
  354.      */
  355.     if (IDM_LINEMIN <= wID && IDM_LINEMAX >=wID)
  356.         {
  357.         CheckLineSelection(wID);
  358.         pDoc->LineStyleSet(wID-IDM_LINEMIN);
  359.         return 0L;
  360.         }
  361.  
  362.     switch (wID)
  363.         {
  364.         case IDM_FILEIMPORT:
  365.             szFile[0]=0;
  366.             fOK=FSaveOpenDialog(szFile, CCHPATHMAX, IDS_FILEIMPORT, TRUE, &i);
  367.  
  368.             if (fOK)
  369.                 {
  370.                 uTemp=pDoc->ULoad(FALSE, szFile);
  371.                 pDoc->ErrorMessage(uTemp);
  372.                 }
  373.  
  374.             return (LRESULT)fOK;
  375.  
  376.  
  377.         case IDM_COLORBACKGROUND:
  378.         case IDM_COLORLINE:
  379.             //Invoke the color chooser for either color
  380.             uTemp=(IDM_COLORBACKGROUND==wID)
  381.                 ? DOCCOLOR_BACKGROUND : DOCCOLOR_LINE;
  382.  
  383.             for (i=0; i<16; i++)
  384.                 rgColors[i]=RGB(0, 0, i*16);
  385.  
  386.             memset(&cc, 0, sizeof(CHOOSECOLOR));
  387.             cc.lStructSize=sizeof(CHOOSECOLOR);
  388.             cc.lpCustColors=rgColors;
  389.             cc.hwndOwner=hWnd;
  390.             cc.Flags=CC_RGBINIT;
  391.             cc.rgbResult=pDoc->ColorGet(uTemp);
  392.  
  393.             if (ChooseColor(&cc))
  394.                 pDoc->ColorSet(uTemp, cc.rgbResult);
  395.  
  396.             break;
  397.  
  398.  
  399.         default:
  400.            CFrame::OnCommand(hWnd, wParam, lParam);
  401.         }
  402.  
  403.     return 0L;
  404.     }
  405.  
  406.  
  407.  
  408.  
  409.  
  410.  
  411. /*
  412.  * CSchmooFrame::OnDocumentDataChange
  413.  *
  414.  * Purpose:
  415.  *  Update the Line menu and GizmoBar if the style in the data changes.
  416.  *
  417.  * Parameters:
  418.  *  pDoc            LPCDocument notifying the sink.
  419.  *
  420.  * Return Value:
  421.  *  None
  422.  */
  423.  
  424. void CSchmooFrame::OnDocumentDataChange(LPCDocument pDoc)
  425.     {
  426.     CheckLineSelection(IDM_LINEMIN+((LPCSchmooDoc)pDoc)->LineStyleGet());
  427.     return;
  428.     }
  429.  
  430.  
  431.  
  432.  
  433. /*
  434.  * CSchmooFrame::OnDocumentActivate
  435.  *
  436.  * Purpose:
  437.  *  Informs us that document activation changed, so update the UI for
  438.  *  that new document.
  439.  *
  440.  * Parameters:
  441.  *  pDoc            LPCDocument notifying the sink.
  442.  *
  443.  * Return Value:
  444.  *  None
  445.  */
  446.  
  447. void CSchmooFrame::OnDocumentActivate(LPCDocument pDoc)
  448.     {
  449.     CheckLineSelection(IDM_LINEMIN+((LPCSchmooDoc)pDoc)->LineStyleGet());
  450.     return;
  451.     }
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459. /*
  460.  * CSchmooFrame::UpdateMenus
  461.  *
  462.  * Purpose:
  463.  *  Handles the WM_INITMENU message for the frame window.  Depending
  464.  *  on the existence of an active window, menu items are selectively
  465.  *  enabled and disabled.
  466.  *
  467.  * Parameters:
  468.  *  hMenu           HMENU of the menu to intialize
  469.  *  iMenu           UINT position of the menu.
  470.  *
  471.  * Return Value:
  472.  *  None
  473.  */
  474.  
  475. void CSchmooFrame::UpdateMenus(HMENU hMenu, UINT iMenu)
  476.     {
  477.     LPCDocument pDoc;
  478.     BOOL        fOK=FALSE;
  479.     BOOL        fCallDefault=TRUE;
  480.     UINT        i;
  481.     UINT        uTemp;
  482.     UINT        uTempE;
  483.     UINT        uTempD;
  484.  
  485.     pDoc=m_pCL->ActiveDocument();
  486.  
  487.     uTempE=MF_ENABLED | MF_BYCOMMAND;
  488.     uTempD=MF_DISABLED | MF_GRAYED | MF_BYCOMMAND;
  489.     uTemp=((NULL!=pDoc) ? uTempE : uTempD);
  490.  
  491.     //File menu:  If there is no current document window, disable Import.
  492.     if (m_phMenu[0]==hMenu)
  493.         EnableMenuItem(hMenu, IDM_FILEIMPORT, uTemp);
  494.  
  495.     //Color menu:  no document, no commands
  496.     if (m_phMenu[2]==hMenu)
  497.         {
  498.         EnableMenuItem(hMenu, IDM_COLORBACKGROUND, uTemp);
  499.         EnableMenuItem(hMenu, IDM_COLORLINE,       uTemp);
  500.         fCallDefault=FALSE;
  501.         }
  502.  
  503.     //Line menu:  no document, no commands
  504.     if (m_phMenu[3]==hMenu)
  505.         {
  506.         for (i=IDM_LINEMIN; i<=IDM_LINEMAX; i++)
  507.             EnableMenuItem(hMenu, i, uTemp);
  508.  
  509.         fCallDefault=FALSE;
  510.         }
  511.  
  512.     if (fCallDefault)
  513.         CFrame::UpdateMenus(hMenu, iMenu);
  514.  
  515.     return;
  516.     }
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523. /*
  524.  * CSchmooFrame::UpdateGizmos
  525.  *
  526.  * Purpose:
  527.  *  Enables and disables gizmos depending on whether we have
  528.  *  a document or not.
  529.  *
  530.  * Parameters:
  531.  *  None
  532.  *
  533.  * Return Value:
  534.  *  None
  535.  */
  536.  
  537. void CSchmooFrame::UpdateGizmos(void)
  538.     {
  539.     LPCDocument pDoc;
  540.     BOOL        fEnable;
  541.     UINT        i;
  542.  
  543.     //Let the default hack on its gizmos.
  544.     CFrame::UpdateGizmos();
  545.  
  546.     pDoc=m_pCL->ActiveDocument();
  547.     fEnable=(NULL!=pDoc);
  548.  
  549.     //No document, disable just about everything
  550.     m_pGB->Enable(IDM_FILEIMPORT, fEnable);
  551.  
  552.     m_pGB->Enable(IDM_COLORBACKGROUND, fEnable);
  553.     m_pGB->Enable(IDM_COLORLINE,       fEnable);
  554.  
  555.     for (i=IDM_LINEMIN; i <= IDM_LINEMAX; i++)
  556.         m_pGB->Enable(i, fEnable);
  557.  
  558.     return;
  559.     }
  560.  
  561.  
  562.  
  563.  
  564.  
  565.  
  566. /*
  567.  * CSchmooFrame::CheckLineSelection
  568.  *
  569.  * Purpose:
  570.  *  Maintains the bitmap menu and the gizmos for the line selection.  Both
  571.  *  are mutially exclusive option lists where a selection in one has to
  572.  *  affect the other.
  573.  *
  574.  * Parameters:
  575.  *  uID             UINT ID of the item to be selected
  576.  *
  577.  * Return Value:
  578.  *  None
  579.  */
  580.  
  581. void CSchmooFrame::CheckLineSelection(UINT uID)
  582.     {
  583.     UINT        i;
  584.     HMENU       hMenu;
  585.  
  586.     hMenu=GetMenu(m_hWnd);
  587.  
  588.     //Uncheck all lines initially.
  589.     for (i=IDM_LINEMIN; i<=IDM_LINEMAX; i++)
  590.         CheckMenuItem(hMenu, i, MF_UNCHECKED | MF_BYCOMMAND);
  591.  
  592.     CheckMenuItem(hMenu, uID, MF_CHECKED | MF_BYCOMMAND);
  593.     m_pGB->Check(uID, TRUE);
  594.     return;
  595.     }
  596.